<?php
namespace app\service;

use think\facade\Log;
use Exception;

class AiTeachingService extends AiService
{
    /**
     * 将笔记内容转换为教案
     */
    public function convertNoteToTeachingPlan(string $note): array
    {
        // 构建提示词
        $prompt = "请将以下笔记内容转换为结构化的教案。要求：
1. 将每个知识点拆分为独立的教案元素
2. 教案前部分为讲解元素，后部分为提问元素
3. 所有提问元素的总分值为10分
4. 每个元素只包含一个基本知识点
5. 提问元素要基于前面讲解过的知识点
6. 严格按照以下JSON数组格式输出（不要包含其他内容）：
[
    {
        \"type\": \"lecture\",           // 讲解类型
        \"point\": \"知识点名称\",
        \"content\": \"讲解内容\",
        \"key_concepts\": [\"关键概念1\", \"关键概念2\"]  // 该知识点的关键概念列表
    },
    {
        \"type\": \"question\",          // 提问类型
        \"point\": \"考察知识点\",
        \"question\": \"具体问题\",
        \"answer\": \"标准答案\",
        \"score\": 3,                    // 分值
        \"passing_score\": 2,            // 及格分数
        \"scoring_criteria\": {          // 评分标准
            \"3\": \"完全正确的标准\",
            \"2\": \"基本正确的标准\",
            \"1\": \"部分正确的标准\",
            \"0\": \"错误或未作答\"
        }
    }
]

笔记内容：
{$note}";

        try {
            // 记录开始处理
            Log::debug('开始转换笔记为教案：', [
                'note_length' => strlen($note)
            ]);
            
            // 构建消息数组
            $messages = [
                [
                    'role' => 'system',
                    'content' => $prompt
                ]
            ];
            
            // 用于存储响应
            $responseText = '';
            
            // 调用AI获取响应
            $this->streamChat($messages, function($chunk) use (&$responseText) {
                $responseText .= $chunk;
            });
            
            Log::debug('AI响应原始内容：', [
                'response' => $responseText
            ]);
            
            // 尝试解析JSON响应
            if (preg_match('/\[.*\]/s', $responseText, $matches)) {
                $jsonStr = $matches[0];
                $teachingPlan = json_decode($jsonStr, true);
                
                if ($teachingPlan) {
                    // 验证教案格式
                    $this->validateTeachingPlan($teachingPlan);
                    
                    // 计算总分
                    $totalScore = 0;
                    $questionCount = 0;
                    foreach ($teachingPlan as $element) {
                        if ($element['type'] === 'question') {
                            $totalScore += $element['score'];
                            $questionCount++;
                        }
                    }
                    
                    Log::info('教案生成完成：', [
                        'total_elements' => count($teachingPlan),
                        'lecture_count' => count(array_filter($teachingPlan, fn($e) => $e['type'] === 'lecture')),
                        'question_count' => $questionCount,
                        'total_score' => $totalScore
                    ]);
                    
                    return $teachingPlan;
                } else {
                    Log::warning('教案JSON解析失败：', [
                        'json_string' => $jsonStr,
                        'json_error' => json_last_error_msg()
                    ]);
                    throw new Exception('教案格式不正确');
                }
            } else {
                Log::warning('未找到有效的JSON数组：', [
                    'response_text' => $responseText
                ]);
                throw new Exception('未能生成有效的教案格式');
            }
            
        } catch (Exception $e) {
            Log::error('教案生成失败：', [
                'error_message' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
            throw $e;
        }
    }

    /**
     * 验证教案格式
     */
    protected function validateTeachingPlan(array $teachingPlan): void
    {
        if (empty($teachingPlan)) {
            throw new Exception('教案内容为空');
        }
        
        $totalScore = 0;
        $hasLecture = false;
        $hasQuestion = false;
        
        foreach ($teachingPlan as $index => $element) {
            if (!isset($element['type'])) {
                throw new Exception("教案元素 {$index} 缺少类型字段");
            }
            
            if (!isset($element['point'])) {
                throw new Exception("教案元素 {$index} 缺少知识点字段");
            }
            
            if ($element['type'] === 'lecture') {
                $hasLecture = true;
                if (!isset($element['content'])) {
                    throw new Exception("讲解元素 {$index} 缺少内容字段");
                }
                if (!isset($element['key_concepts']) || !is_array($element['key_concepts'])) {
                    throw new Exception("讲解元素 {$index} 缺少或关键概念格式错误");
                }
            } elseif ($element['type'] === 'question') {
                $hasQuestion = true;
                if (!isset($element['question'])) {
                    throw new Exception("提问元素 {$index} 缺少问题字段");
                }
                if (!isset($element['answer'])) {
                    throw new Exception("提问元素 {$index} 缺少答案字段");
                }
                if (!isset($element['score']) || !is_numeric($element['score'])) {
                    throw new Exception("提问元素 {$index} 缺少或分值格式错误");
                }
                if (!isset($element['passing_score']) || !is_numeric($element['passing_score'])) {
                    throw new Exception("提问元素 {$index} 缺少或及格分数格式错误");
                }
                if (!isset($element['scoring_criteria']) || !is_array($element['scoring_criteria'])) {
                    throw new Exception("提问元素 {$index} 缺少或评分标准格式错误");
                }
                
                $totalScore += $element['score'];
            } else {
                throw new Exception("教案元素 {$index} 类型无效");
            }
        }
        
        if (!$hasLecture) {
            throw new Exception('教案中缺少讲解元素');
        }
        
        if (!$hasQuestion) {
            throw new Exception('教案中缺少提问元素');
        }
        
        if ($totalScore !== 10) {
            throw new Exception("提问元素总分不等于10分（当前：{$totalScore}分）");
        }
    }
} 